home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Telnet 2.5.src.ThinkC / source / ser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-07  |  11.8 KB  |  402 lines  |  [TEXT/KAHL]

  1. /* File:  serial.c
  2. *
  3. *  Developer:        Jim Logan
  4. *  Organization:    Brigham Young University
  5. *  Email:        loganj@byuvax.bitnet
  6. *             loganj@yvax.byu.edu
  7. *
  8. *   Captures incoming data from the active serial port and
  9. *   provides control of serial port characteristics (baud 
  10. *   rate, parity, stop bits, handshaking ... ).
  11. *
  12. */
  13.  
  14. #include <Quickdraw.h>
  15. #include <Devices.h>
  16. #include <Files.h>
  17. #include <Serial.h>
  18. #include <Dialogs.h>
  19. #include "Packages.h"
  20. #include <stdio.h>
  21.  
  22. #include <ToolUtils.h>
  23.  
  24. #include "whatami.h"
  25. #include "wind.h"
  26.  
  27. #define input_size 8192
  28.  
  29. #define SPEED_RESOURCE_ID 23231
  30. #define DATABITS_RESOURCE_ID 23232
  31. #define PARITY_RESOURCE_ID 23233
  32. #define STOPBITS_RESOURCE_ID 23234
  33. #define CHOOSEPORT_RESOURCE_ID 23235
  34. #define HANDSHAKE_RESOURCE_ID 23236
  35.  
  36. extern int numwindows;
  37.  
  38. static ResType
  39.   Setres = 'CNFG';
  40.  
  41. static unsigned char   *minputnam[] = {"\p.ain","\p.bin"};
  42. static unsigned char   *moutputnam[] = {"\p.aout","\p.bout"};
  43.  
  44. #if 0
  45. static unsigned char  *mbtext[] = {
  46.   "\p300 baud","\p600 baud","\p1200 baud","\p1800 baud","\p2400 baud",
  47.   "\p3600 baud","\p4800 baud","\p7200 baud","\p9600 baud",
  48.     "\p19200 baud","\p57600 baud", 0};
  49. static unsigned char  *mdtext[] = {"\p5 data bits","\p6 data bits","\p7 data bits","\p8 data bits", 0};
  50. static unsigned char  *mptext[] = {"\pNo parity","\pOdd parity","\pEven parity", 0};
  51. static unsigned char  *mstext[] = {"\p1 stop bit","\p1.5 stop bits","\p2 stop bits", 0};
  52. static unsigned char  *mPorttext[] = {"\pModem Port","\pPrinter Port", 0};
  53. static unsigned char  *mprottext[] = {"\pNo handshaking","\pXon/Xoff Handshaking", 0};
  54. #endif
  55.  
  56. static int  mbtable[]     = 
  57.   { baud300, baud600,
  58.     baud1200,baud1800,
  59.     baud2400,baud3600,
  60.     baud4800,baud7200,
  61.     baud9600,baud19200,baud57600};
  62.  
  63. static int  mdtable[]     = {data5,data6,data7,data8};
  64. static int  mptable[]     = {noParity,oddParity,evenParity};
  65. static int  mstable[]     = {stop10,stop15,stop20};
  66. static int  minputnum[] = {-6,-8};    /* File numbers of incoming modem/printer ports */
  67. static int  moutputnum[] = {-7,-9};    /* File numbers of outgoing modem/printer ports */
  68. static unsigned char mramnum[] = {sPortA, sPortB};
  69.  
  70. static SerShk shakies = 
  71.   { (char)0,
  72.     (char)0,
  73.     (char)17,    /* "xon" character is control q */
  74.     (char)19,    /* "xoff" character is control s */
  75.     (char)0,
  76.     (char)0,
  77.     (char)1,    /* "fInX" field: enable incoming "xon/xoff" handshaking */
  78.     (char)0};
  79.  
  80. unsigned char 
  81.   SLIP_ip_number[4],
  82.   DTRleaveon = 0x80,
  83.   DTRturnoff = 0x80;
  84.  
  85. short
  86.   serial_scrn=-1,
  87.   slip_connection=0,    /* 0 = serial, 1 = slip */
  88.   mpi,            /* Modem input file refnum */
  89.   mpo,            /* Modem output file refnum */
  90.   mbaud,            /* Port speed         */
  91.   mdata,            /* Port data bits     */
  92.   mparity,          /* Port parity         */
  93.   mport,            /* Port selected     */
  94.   mprot,            /* Port protocol     */
  95.   mstop;            /* Port stop bits     */
  96.  
  97. char 
  98.   *modembuf,
  99.   *incoming;
  100.  
  101. extern WindRec *screens;
  102.  
  103. /* Get the (program settings) "CNFG" resource */
  104.  
  105. getSettings() {
  106. char **myResource; unsigned short *resptr;
  107. #define    SettingsID    31324
  108.  
  109.     myResource = GetResource( Setres, SettingsID);
  110.     resptr = (unsigned short*) *myResource;
  111.     SetSettings(resptr);
  112.       ReleaseResource(myResource);
  113. }
  114.  
  115.  
  116. /* Set the program settings from the "CNFG" resource */
  117.  
  118. SetSettings(rp) unsigned short *rp; {
  119. unsigned short *resptr;
  120. unsigned short i;
  121.   resptr = rp;
  122.   mbaud     = *(resptr++);
  123.   mdata     = *(resptr++);
  124.   mparity     = *(resptr++);
  125.   mport     = *(resptr++);
  126.   mprot     = *(resptr++);
  127.   mstop     = *(resptr++);
  128.   i        = *(resptr++);
  129.   SLIP_ip_number[0] = (i >> 8) & 0xff;
  130.   SLIP_ip_number[1] = i & 0xff;
  131.   i        = *(resptr++);
  132.   SLIP_ip_number[2] = (i >> 8) & 0xff;
  133.   SLIP_ip_number[3] = i & 0xff;
  134. }
  135.  
  136.  
  137. /* Save the program settings in the "CNFG" resource */
  138.  
  139. saveSettings() {
  140. Point     myPoint;
  141. unsigned short     *resptr;
  142. char     **myResource; 
  143. GrafPtr tempPort;
  144.  
  145.   GetPort(&tempPort);
  146.   myResource = GetResource( Setres, SettingsID);
  147.   resptr = (unsigned short*) *myResource;
  148.   *(resptr++) = mbaud;
  149.   *(resptr++) = mdata;
  150.   *(resptr++) = mparity;
  151.   *(resptr++) = mport;
  152.   *(resptr++) = mprot;
  153.   *(resptr++) = mstop;
  154.   *(resptr++) = (SLIP_ip_number[0] << 8) | SLIP_ip_number[1];
  155.   *(resptr++) = (SLIP_ip_number[2] << 8) | SLIP_ip_number[3];
  156.           
  157.   ChangedResource(myResource);
  158.   WriteResource(myResource);
  159.   ReleaseResource(myResource);
  160.   SetPort(tempPort);
  161. }
  162.  
  163. /* Open a serial port, use the "incoming" buffer, and 
  164.    set "xon/xoff" handshaking on */
  165.  
  166. PortOpen() {
  167. short fstatus,mSettings;
  168. #if 0
  169.   fstatus = RAMSDOpen(mramnum[mport]);
  170. #endif
  171.  
  172.   fstatus = OpenDriver(minputnam[mport],&mpi);
  173.   fstatus = OpenDriver(moutputnam[mport],&mpo);
  174.  
  175.   mSettings = mbtable[mbaud] + mdtable[mdata] + mptable[mparity] + mstable[mstop];
  176.   fstatus = SerReset(mpi,mSettings);
  177.   fstatus = SerReset(mpo,mSettings);
  178.   fstatus = SerSetBuf(mpi,incoming,input_size);    /* Input buffer specification */
  179.   shakies.fInX = (char) mprot;
  180.   fstatus = SerHShake(mpi,&shakies);        /* Handshake parameters */
  181.   Control(mpo,16,(const void *) &DTRleaveon);    /* Leave DTR alone on close */
  182.   Control(mpo,17,(const void *) 0);        /* Enable DTR */
  183. }
  184.  
  185.  
  186. /* Close the serial port */
  187.  
  188. PortClose() {
  189. short fstatus;
  190.   if (mpi != 0) { 
  191.     fstatus = CloseDriver(mpi);
  192.     mpi = 0; 
  193.   }
  194.   if (mpo != 0) { 
  195.     fstatus = CloseDriver(mpo);
  196.     mpo = 0; 
  197.   } 
  198. #if 0
  199.   RAMSDClose(mramnum[mport]);
  200. #endif
  201. }
  202.  
  203.  
  204. /* This function checks to see if there is any data coming into 
  205.    the serial port, and if so captures the data. */
  206.  
  207. DoModem() {
  208. OSErr     mpistatus;    /* mpi is modem.port.in    */
  209. long    fcount,mpicount;
  210. int    fstatus;
  211. unsigned char c;
  212.  
  213.   if (serial_scrn >= 0) {
  214.     mpistatus = SerGetBuf(mpi, &mpicount);        /* How much data is coming? */
  215.     if ((mpistatus == noErr) && (mpicount > 0)) {    /* Number of characters. */
  216.  
  217.       fcount = mpicount;
  218.       fstatus = FSRead(mpi, &fcount, modembuf);    /* Read all of the data. */
  219.       if (slip_connection)
  220.         SLIPreceive(modembuf, (int) fcount);
  221.       else
  222.         parse(&screens[serial_scrn], modembuf, (int) fcount);
  223. } } }
  224.  
  225.  
  226. /* Paint a wide border around button #1 to indicate which 
  227.    button is the default button */
  228.  
  229. PaintDial(myDialog)     /* Circle OK    item 1    */
  230. DialogPtr myDialog; {
  231. int     item_type;
  232. Handle     item_Handle;  
  233. Rect     item_box; 
  234.  
  235.   SetPort(    myDialog);
  236.   GetDItem(    myDialog,1,&item_type,&item_Handle,&item_box);
  237.   item_box.left--; item_box.top--;    /* TBD:  use InsetRect() */
  238.   item_box.right++; item_box.bottom++;
  239.   PenSize(3,3);
  240.   InsetRect(      &item_box,-3,-3);
  241.   FrameRoundRect( &item_box,16,16);
  242. }
  243.  
  244.  
  245. /* GetDIHandle - return handle value of dialog item */
  246.  
  247. Handle GetDIHandle(theDia,i) DialogPtr theDia;int i; {
  248. int theType;
  249. Handle theHandle;
  250. Rect theRect;
  251.   GetDItem(theDia, i, &theType, &theHandle, &theRect);
  252.   return theHandle;
  253. }
  254.  
  255.  
  256. /* Restrict the value of an integer to between "lo" and "hi" */
  257.  
  258. int BoundsLimitWithWrapAround( vPtr, lo, hi) short *vPtr, lo, hi; {
  259.   if( *vPtr < lo) *vPtr = hi;
  260.   else if( *vPtr > hi) *vPtr = lo;
  261.   return( *vPtr);
  262. }
  263.  
  264.  
  265. /* Set the characteristics of the serial port */
  266.  
  267. Setmodem() {
  268. GrafPtr     tempPort;
  269. short     the_item,tbaud,tdata,tparity,tport,tprot,tstop;
  270. DialogPtr myDialog;
  271. unsigned char TEMP_ip_number[4];
  272. char     item_text[256];  
  273.  
  274.   InitCursor();  
  275.   GetPort(&tempPort);
  276. #define MODEM_DLOD_ID    28243
  277.  
  278.   myDialog = GetNewDialog( MODEM_DLOD_ID,(DialogPeek) 0L, (WindowPtr)-1L);  
  279.   PaintDial(myDialog);
  280.  
  281.   GetIndString(item_text,SPEED_RESOURCE_ID,mbaud+1);
  282.   SetIText( GetDIHandle( myDialog, 15),  (Str255 *) item_text);
  283.   GetIndString(item_text,DATABITS_RESOURCE_ID,mdata+1);
  284.   SetIText( GetDIHandle( myDialog, 16),  (Str255 *) item_text);
  285.   GetIndString(item_text,PARITY_RESOURCE_ID,mparity+1);
  286.   SetIText( GetDIHandle( myDialog, 17),  (Str255 *) item_text);
  287.   GetIndString(item_text,STOPBITS_RESOURCE_ID,mstop+1);
  288.   SetIText( GetDIHandle( myDialog, 18),  (Str255 *) item_text);
  289.   GetIndString(item_text,CHOOSEPORT_RESOURCE_ID,mport+1);
  290.   SetIText( GetDIHandle( myDialog, 19),  (Str255 *) item_text);
  291.   GetIndString(item_text,HANDSHAKE_RESOURCE_ID,mprot+1);
  292.   SetIText( GetDIHandle( myDialog, 20),  (Str255 *) item_text);
  293.   sprintf(item_text,"%d.%d.%d.%d", (int) SLIP_ip_number[0], 
  294.     (int) SLIP_ip_number[1], (int) SLIP_ip_number[2],(int) SLIP_ip_number[3]);
  295.   c2pstr((char *) item_text);
  296.   SetIText( GetDIHandle( myDialog, 21),  (Str255 *) item_text);
  297.   SelIText( myDialog,21,0,32767);
  298.  
  299.   tbaud = mbaud; tdata = mdata; tparity = mparity; 
  300.   tport = mport; tprot = mprot; tstop = mstop;
  301.   TEMP_ip_number[0] = SLIP_ip_number[0];
  302.   TEMP_ip_number[1] = SLIP_ip_number[1];
  303.   TEMP_ip_number[2] = SLIP_ip_number[2];
  304.   TEMP_ip_number[3] = SLIP_ip_number[3];
  305.   
  306.   do { 
  307.     ModalDialog((long) 0,&the_item); 
  308.     if ((the_item == 3) || (the_item == 4) ) {        /* UP/DOWN tbaud */
  309.       tbaud += ((the_item == 3 /* UP*/) ? 1 : -1);
  310.       BoundsLimitWithWrapAround( &tbaud, 0, 10);
  311.       GetIndString(item_text,SPEED_RESOURCE_ID,tbaud+1);
  312.       SetIText( GetDIHandle( myDialog, 15),  (Str255 *) item_text);
  313.     } else if ((the_item == 5) || (the_item == 6)) {    /* UP/DOWN tdata */
  314.       tdata += ((the_item == 5 /* UP*/) ? 1 : -1);     
  315.       BoundsLimitWithWrapAround( &tdata, 0, 3);
  316.       GetIndString(item_text,DATABITS_RESOURCE_ID,tdata+1);
  317.       SetIText( GetDIHandle( myDialog, 16),  (Str255 *) item_text);
  318.     } else if ((the_item == 7) || (the_item == 8)) {    /* UP/DOWN tparity */
  319.       tparity += ((the_item == 7 /* UP*/) ? 1 : -1);
  320.       BoundsLimitWithWrapAround( &tparity, 0, 2);
  321.       GetIndString(item_text,PARITY_RESOURCE_ID,tparity+1);
  322.       SetIText( GetDIHandle( myDialog, 17),  (Str255 *) item_text);
  323.     } else if ((the_item == 9) || (the_item == 10)) {    /* UP/DOWN tstop */
  324.       tstop += ((the_item == 9 /* UP*/) ? 1 : -1);
  325.       BoundsLimitWithWrapAround( &tstop, 0, 2);
  326.       GetIndString(item_text,STOPBITS_RESOURCE_ID,tstop+1);
  327.       SetIText( GetDIHandle( myDialog, 18),  (Str255 *) item_text);
  328.     } else if ((the_item == 11) || (the_item == 12)) {    /* UP/DOWN tport */
  329.       tport += ((the_item == 11 /* UP*/) ? 1 : -1);
  330.       BoundsLimitWithWrapAround( &tport, 0, 1);
  331.       GetIndString(item_text,CHOOSEPORT_RESOURCE_ID,tport+1);
  332.       SetIText( GetDIHandle( myDialog, 19),  (Str255 *) item_text);
  333.     } else if ((the_item == 13) || (the_item == 14)) {    /* UP/DOWN tpROt */
  334.       tprot += ((the_item == 13 /* UP*/) ? 1 : -1);
  335.       BoundsLimitWithWrapAround( &tprot, 0, 1);
  336.       GetIndString(item_text,HANDSHAKE_RESOURCE_ID,tprot+1);
  337.       SetIText( GetDIHandle( myDialog, 20),  (Str255 *) item_text);
  338.     } else if (the_item == 21) {            /* SLIP IP number */
  339.       GetIText( GetDIHandle( myDialog, 21),  (Str255 *) item_text);
  340.       p2cstr((char *) item_text);
  341.       decodeIPnum(item_text,&TEMP_ip_number[0]);
  342.     }
  343.   } while ((the_item != OK) && (the_item != Cancel));
  344.   
  345.   if (the_item == OK)             /* Save temps to theRealThings    */
  346.   {
  347.     PortClose();
  348.     mbaud = tbaud; mdata = tdata; mparity = tparity; 
  349.     mport = tport; mprot = tprot; mstop = tstop;
  350.     SLIP_ip_number[0] = TEMP_ip_number[0];
  351.     SLIP_ip_number[1] = TEMP_ip_number[1];
  352.     SLIP_ip_number[2] = TEMP_ip_number[2];
  353.     SLIP_ip_number[3] = TEMP_ip_number[3];
  354.     saveSettings();
  355.     PortOpen();
  356.   }
  357.   CloseDialog( myDialog); 
  358.   SetPort(tempPort);
  359.   return( the_item);
  360. }
  361.  
  362. write_serial(buffer,nsend) char *buffer; int nsend; {
  363. long byte_count;
  364. int fstatus;
  365.   byte_count = nsend;
  366.   fstatus = FSWrite(mpo,&byte_count,buffer);
  367. }
  368.  
  369. /* Initialize serial i/o */
  370.  
  371. init_serial() {
  372. long mysize;
  373.     serial_scrn = -1;
  374.     getSettings();
  375.     mysize = input_size;
  376.     modembuf = NewPtr(mysize);
  377.     incoming = NewPtr(mysize);
  378. }
  379.  
  380. int open_serial(pnum) int pnum; {
  381.   if (serial_scrn < 0) {
  382.     serial_scrn = numwindows;
  383.     PortOpen();                    /* Open the serial port */
  384.     return pnum;
  385.   }
  386.   OtherError((char *) "\pError opening serial port.",(char *) "\pSerial port already open.");        /* BYU serial */
  387.   return -1;
  388. }
  389.  
  390. int close_serial() {
  391.   serial_scrn = -1;
  392.   if (mpo != 0) 
  393.     PortClose();
  394. }
  395.  
  396. serial_shut() {
  397.   serial_scrn = -1;
  398.   if (mpo != 0) {
  399.     Control(mpo,16,(const void *) &DTRturnoff);    /* Don't leave DTR alone on close */
  400.     Control(mpo,18,(const void *) 0);        /* Disable DTR */
  401. } }
  402.